package com.party.admin.biz.copartner;

import com.google.common.base.Function;
import com.party.admin.web.dto.output.copartner.AnalyzeListOutput;
import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.core.model.copartner.BrokerageItem;
import com.party.core.model.copartner.BrokerageStatusEnum;
import com.party.core.model.distributor.DistributorDetail;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.member.*;
import com.party.core.model.wallet.Withdrawals;
import com.party.core.service.activity.IActivityInfoService;
import com.party.core.service.copartner.IBrokerageItemService;
import com.party.core.service.crowdfund.IProjectService;
import com.party.core.service.distributor.IDistributorCountService;
import com.party.core.service.distributor.IDistributorDetailService;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.member.*;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.wallet.biz.WithdrawalsBizService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 合伙人统计数据
 * Created by wei.li.
 *
 * @date 2018/1/17 0017
 * @time 11:35
 */

@SuppressWarnings("all")
@Service
public class MemberCopartnerDetailBizService {

    @Autowired
    private ICopartnerAnalyzeService copartnerAnalyzeService;

    @Autowired
    private IMemberCopartnerDetailService memberCopartnerDetailService;

    @Autowired
    private IMemberCopartnerCountService memberCopartnerCountService;

    @Autowired
    private IMemberService memberService;

    @Autowired
    private IMemberActService memberActService;

    @Autowired
    private IOrderFormService orderFormService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IBrokerageItemService brokerageItemService;

    @Autowired
    private IDistributorDetailService distributorDetailService;

    @Autowired
    private IDistributorRelationService distributorRelationService;

    @Autowired
    private IDistributorCountService distributorCountService;

    @Autowired
    private WithdrawalsBizService withdrawalsBizService;

    @Autowired
    private IActivityInfoService activityInfoService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 初始化合伙人数据统计
     */
    public void init() {

        //统计总计
        List<CopartnerAnalyze> sumList = copartnerAnalyzeService.sumList(new CopartnerAnalyzeQuery(), null);
        for (CopartnerAnalyze copartnerAnalyze : sumList) {
            MemberCopartnerCount memberCopartnerCount = memberCopartnerCountService.getSet(copartnerAnalyze.getMemberId());
            memberCopartnerCount.setOrderNum(copartnerAnalyze.getOrderNum());
            memberCopartnerCount.setApplyNum(copartnerAnalyze.getApplyNum());
            memberCopartnerCount.setSuccessNum(copartnerAnalyze.getSuccessNum());
            memberCopartnerCount.setTotalMoney(copartnerAnalyze.getTotalMoney());
            memberCopartnerCount.setTotalBrokerage(copartnerAnalyze.getTotalBrokerage());
            memberCopartnerCountService.update(memberCopartnerCount);
        }

        List<CopartnerAnalyze> list = copartnerAnalyzeService.list(new CopartnerAnalyze());
        for (CopartnerAnalyze copartnerAnalyze : list) {

            //统计详情
            MemberCopartnerDetail memberCopartnerDetail
                    = memberCopartnerDetailService.getSet(copartnerAnalyze.getMemberId(), copartnerAnalyze.getCreateDate());

            memberCopartnerDetail.setOrderNum(copartnerAnalyze.getOrderNum());
            memberCopartnerDetail.setApplyNum(copartnerAnalyze.getApplyNum());
            memberCopartnerDetail.setSuccessNum(copartnerAnalyze.getSuccessNum());
            memberCopartnerDetail.setTotalMoney(copartnerAnalyze.getTotalMoney());
            memberCopartnerDetail.setTotalBrokerage(copartnerAnalyze.getTotalBrokerage());
            memberCopartnerDetailService.update(memberCopartnerDetail);
        }
    }


    /**
     * 初始化今天的合作商数据
     */
    public void todayDate() {
        List<String> list = memberService.getAllChannelDis();
        Date date = DateUtils.today();
        String dateStr = DateUtils.formatDate(date);

        for (String mId : list) {
            try {
                // 报名数
                Integer applyNum = memberActService.disCount(mId, dateStr, dateStr);

                // 订单数 累计资金
                Map<String, Object> orderData = orderFormService.disCount(mId, dateStr, dateStr);
                Integer orderNum = (Integer) orderData.get("orderNum");
                Double totalMoney = (Double) orderData.get("totalMoney");

                // 众筹成功人数
                Integer successNum = projectService.disCount(mId, dateStr, dateStr);

                // 累计佣金
                Double totalBrokerage = brokerageItemService.getMyBrokerage(mId, null, dateStr, dateStr, true);

                // 我的佣金
                Double myBrokerage = brokerageItemService.getMyBrokerage(mId, null, dateStr, dateStr, false);

                // 未结算
                Double notBalance = brokerageItemService.getMyBrokerage(mId, BrokerageItem.STATUS_NOT_BROKERAGE, dateStr, dateStr, true);

                // 可结算
                Double balance = brokerageItemService.getMyBrokerage(mId, BrokerageItem.STATUS_CAN_BROKERAGE, dateStr, dateStr, true);

                // 累计提现佣金
                Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(mId, Withdrawals.TYPE_BROKERAGE,null);

                // 可提现佣金
                double canWithdrawal = BigDecimalUtils.sub(balance, withdrawalTotal);

                MemberCopartnerDetail memberCopartnerDetail = memberCopartnerDetailService.getSet(mId, date);
                memberCopartnerDetail.setApplyNum(applyNum);
                memberCopartnerDetail.setOrderNum(orderNum);
                memberCopartnerDetail.setSuccessNum(successNum);
                memberCopartnerDetail.setTotalMoney(totalMoney);
                memberCopartnerDetail.setTotalBrokerage(totalBrokerage);
                memberCopartnerDetail.setMyBrokerage(myBrokerage);
                memberCopartnerDetail.setNotBalance(notBalance);
                memberCopartnerDetail.setCanWithdrawal(BigDecimalUtils.round(canWithdrawal, 2));
                memberCopartnerDetailService.update(memberCopartnerDetail);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    /**
     * 转换统计总计
     *
     * @param list 列表数据
     * @return 输出视图
     */
    public List<AnalyzeListOutput> transformCount(List<MemberCopartnerCountWithMember> list) {
        return LangUtils.transform(list, new Function<MemberCopartnerCountWithMember, AnalyzeListOutput>() {
            @Override
            public AnalyzeListOutput apply(MemberCopartnerCountWithMember memberCopartnerCountWithMember) {
                return AnalyzeListOutput.transform(memberCopartnerCountWithMember);
            }
        });
    }

    /**
     * 转换统计详情
     *
     * @param list 列表数据
     * @return 输出视图
     */
    public List<AnalyzeListOutput> transformDetail(List<MemberCopartnerDetailWithMember> list) {
        return LangUtils.transform(list, new Function<MemberCopartnerDetailWithMember, AnalyzeListOutput>() {
            @Override
            public AnalyzeListOutput apply(MemberCopartnerDetailWithMember memberCopartnerDetailWithMember) {
                return AnalyzeListOutput.transform(memberCopartnerDetailWithMember);
            }
        });
    }


    /**
     * 合伙人数据分析
     *
     * @param copartnerAnalyzeQuery 查询条件
     * @param page                  分页参数
     * @return 输出视图
     */
    public List<AnalyzeListOutput> list(CopartnerAnalyzeQuery copartnerAnalyzeQuery, Page page) {
        if (null != copartnerAnalyzeQuery.getTimeType()
                && !copartnerAnalyzeQuery.getTimeType().equals(0)
                && !copartnerAnalyzeQuery.getTimeType().equals(5)) {

            String now = DateUtils.todayDate();
            String endTime = DateUtils.todayDate();
            String startTime = null;
            if (copartnerAnalyzeQuery.getTimeType().equals(1)) {
                startTime = now;
            } else if (copartnerAnalyzeQuery.getTimeType().equals(2)) {
                startTime = DateUtils.formatDate(DateUtils.addDay(now, -1));
                endTime = startTime;
            } else if (copartnerAnalyzeQuery.getTimeType().equals(3)) {
                startTime = DateUtils.formatDate(DateUtils.getFirstDayOfWeek(0));
                endTime = DateUtils.formatDate(DateUtils.getLastDayOfWeek(0));
            } else if (copartnerAnalyzeQuery.getTimeType().equals(4)) {
                startTime = DateUtils.formatDate(DateUtils.getFirstDayOfMonth(0));
                endTime = DateUtils.formatDate(DateUtils.getLastDayOfMonth(0));
            }
            copartnerAnalyzeQuery.setCreateStart(startTime);
            copartnerAnalyzeQuery.setCreateEnd(endTime);
            List<MemberCopartnerDetailWithMember> list
                    = memberCopartnerDetailService.sumList(copartnerAnalyzeQuery, page);
            return this.transformDetail(list);
        }
        List<MemberCopartnerCountWithMember> list
                = memberCopartnerCountService.queryList(copartnerAnalyzeQuery, page);
        return this.transformCount(list);
    }

    /**
     * 更新众筹成功数
     *
     * @param projectId 众筹编号
     */
    public void updateSuccess(String projectId) {
        DistributorDetail distributorDetail = distributorDetailService.findByTargetId(projectId);
        if (null != distributorDetail) {
            DistributorRelation distributorRelation = distributorRelationService.get(distributorDetail.getDistributorRelationId());
            if (null != distributorRelation
                    && (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType()))
                    || DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                String distributorId = distributorRelation.getDistributorId();

                memberCopartnerCountService.updateSuccess(projectId, distributorId);

                memberCopartnerDetailService.updateSuccess(projectId, distributorId);
            }
        }
    }

    /**
     * 更新众筹成功数
     *
     * @param projectId 众筹编号
     */
    public void updateSuccessSub(String projectId, Date createDate) {
        DistributorDetail distributorDetail = distributorDetailService.findByTargetId(projectId);
        if (null != distributorDetail) {
            DistributorRelation distributorRelation = distributorRelationService.get(distributorDetail.getDistributorRelationId());
            if (null != distributorRelation
                    && (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType()))
                    || DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                String distributorId = distributorRelation.getDistributorId();

                String formatDate = DateUtils.formatDate(createDate, DateUtils.DATE_PATTERN);
                String formatToday = DateUtils.formatDate(new Date(), DateUtils.DATE_PATTERN);
                String option = formatToday.equals(formatDate) ? Constant.OPTION_ADD : Constant.OPTION_SUB;

                memberCopartnerCountService.updateSuccessSub(projectId, distributorId);

                memberCopartnerDetailService.updateSuccessSub(projectId, distributorId, option);
            }
        }
    }

    /**
     * 更新订单数和金额数
     *
     * @param projectId 众筹编号
     * @param payment   支付数
     */
    public void updateOrderAnalyze(String projectId, Float payment) {
        DistributorDetail distributorDetail = distributorDetailService.findByTargetId(projectId);
        if (null != distributorDetail) {
            DistributorRelation distributorRelation = distributorRelationService.get(distributorDetail.getDistributorRelationId());
            if (null != distributorRelation
                    && (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType()))
                    || DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                String distributorId = distributorRelation.getDistributorId();

                memberCopartnerCountService.updateOrderAnalyze(payment, distributorId);

                memberCopartnerDetailService.updateOrderAnalyze(payment, distributorId);
            }
        }
    }

    /**
     * 更新报名数
     *
     * @param projectId 众筹编号
     */
    public void updateApplyNum(String projectId) {
        DistributorDetail distributorDetail = distributorDetailService.findByTargetId(projectId);
        if (null != distributorDetail) {
            DistributorRelation distributorRelation = distributorRelationService.get(distributorDetail.getDistributorRelationId());
            if (null != distributorRelation
                    && (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType()))
                    || DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                String distributorId = distributorRelation.getDistributorId();

                memberCopartnerCountService.updateApplyNum(projectId, distributorId);

                memberCopartnerDetailService.updateApplyNum(projectId, distributorId);
            }
        }
    }

    @Transactional
    public void activityApplyRefund(String relationId, String targetId, double payment) {
        try {
            DistributorRelation distributorRelation = distributorRelationService.get(relationId);
            if (null != distributorRelation && DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                MemberAct memberAct = memberActService.get(targetId);

                String formatDate = DateUtils.formatDate(memberAct.getCreateDate(), DateUtils.DATE_PATTERN);
                String formatToday = DateUtils.formatDate(new Date(), DateUtils.DATE_PATTERN);
                String option = formatToday.equals(formatDate) ? Constant.OPTION_ADD : Constant.OPTION_SUB;

                memberCopartnerDetailService.updateApplyRefund(distributorRelation.getDistributorId(), payment, option);
                memberCopartnerCountService.updateApplyRefund(distributorRelation.getDistributorId(), payment);

                List<BrokerageItem> brokerageItems = brokerageItemService.findByTargetId(memberAct.getId());
                brokerageItems.forEach(new Consumer<BrokerageItem>() {
                    @Override
                    public void accept(BrokerageItem brokerageItem) {
                        if (BrokerageStatusEnum.TWO_WITHDRAW.getCode().equals(brokerageItem.getCheckStatus())) {
//                            ActivityInfo activityInfo = activityInfoService.findByActivityId(brokerageItem.getActivityId());
//                            // 是否可提现
//                            boolean isBegin = false;
//                            if (null != activityInfo.getWithdrawDate() && activityInfo.getWithdrawDate().before(new Date())) {
//                                isBegin = true;
//                            }
                            boolean isMyBrokerage = brokerageItem.getParentId().equals("-1") ? true : false;
                            String partnerId = isMyBrokerage ? brokerageItem.getPartnerId() : brokerageItem.getParentId();

//                            Double withdrawalTotal = withdrawalsBizService.getWithdrawalTotal(partnerId, Withdrawals.TYPE_BROKERAGE);

                            memberCopartnerDetailService.updateApplyRefundBrokerage(partnerId, brokerageItem.getBrokerage(),
                                    isMyBrokerage, option, false, 0);

                            memberCopartnerCountService.updateApplyRefundBrokerage(partnerId, brokerageItem.getBrokerage(),
                                    isMyBrokerage, false, 0);

                            brokerageItem.setUpdateDate(null);
                            brokerageItem.setCreateDate(null);
                            brokerageItem.setCheckStatus(BrokerageStatusEnum.TWO_REJECT.getCode());
                            brokerageItemService.update(brokerageItem);
                        }
                    }
                });
            }
        } catch (Exception e) {
            logger.error("活动/课程退款后，合伙人数据处理异常", e);
        }
    }

    /**
     * 更新报名数
     *
     * @param distributorRelation 分销关系
     * @param createDate          创建时间
     */
    @Transactional
    public void updateApplyNumSub(DistributorRelation distributorRelation, Date createDate) {
        if (null != distributorRelation && (
                DistributorRelationType.COURSE_DISTRIBUTION.getCode().equals(distributorRelation.getType())
                        || DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType()))) {

            String formatDate = DateUtils.formatDate(createDate, DateUtils.DATE_PATTERN);
            String formatToday = DateUtils.formatDate(new Date(), DateUtils.DATE_PATTERN);
            String option = formatToday.equals(formatDate) ? Constant.OPTION_ADD : Constant.OPTION_SUB;

            memberCopartnerCountService.updateApplyRefund(distributorRelation.getDistributorId(), 0d);
            memberCopartnerDetailService.updateApplyRefund(distributorRelation.getDistributorId(), 0d, option);
        }
    }
}
